<?php
namespace App\Service\OrderService\OrderInterfaceService;
use App\Model\CommodityModel\SupplierCompany;
use App\Model\PssModel\OrderSettlement;
use App\Model\PssModel\OrderSupplierGoods;
use App\Service\BaseService;
use App\Service\Code\Normal;
use App\Model\PssModel\OrderRefund;
use App\Service\OrderService\OrderRefundService\OrderRefundMessage;
use App\Model\PssModel\OrderRefundLog;
use App\Model\PssModel\OrderSupplier;
use App\Model\PssModel\Business;
use App\Service\PushService\BusinessPushService;

/**
 * 售后审核接口
 */
class OrderAfterSaleVerify extends BaseService
{
    const AFTER_SALE_VERIFY_PASS = 1;
    const AFTER_SALE_VERIFY_REJECT = 2;
    public $channel_order_types=[0,10];
    
    /**
     * 订单售后处理
     */
    public function index( $param = [] )
    {
        if( empty($param['requestData']) ) {
            return Normal::returnCode(Normal::FAIL,"订单数据不能为空");
        }
        $requestData = $param['requestData'];
        if( empty($requestData['refundID']) ) {
            return Normal::returnCode(Normal::FAIL,"售后订单refundID不能为空");
        }
        
        if( !isset($requestData['afterVerifyRemark']) ) {
            return Normal::returnCode(Normal::FAIL,"afterVerifyRemark售后原因不能为空");
        }
        
        if( !isset($requestData['afterVerifyStatus']) ) {
            return Normal::returnCode(Normal::FAIL,"afterVerifyStatus参数缺失");
        }
        
        if( !in_array($requestData['afterVerifyStatus'],[self::AFTER_SALE_VERIFY_REJECT,self::AFTER_SALE_VERIFY_PASS]) ) {
            return Normal::returnCode(Normal::FAIL,"afterVerifyStatus状态值必须在1,2之间");
        }
        
        if( $requestData['afterVerifyStatus'] == self::AFTER_SALE_VERIFY_REJECT && empty($requestData['afterVerifyRemark']) ) {
            return Normal::returnCode(Normal::FAIL,"审核拒绝原因,客服备注不能为空");
        }

        if( empty($requestData['sysUserID']) && (!isset($requestData['is_inner_call_mode']) || empty($requestData['is_inner_call_mode']))) {
            return Normal::returnCode(Normal::FAIL,"sysUserID不能为空");
        }
        
        if( empty($requestData['sysUserName']) ) {
            return Normal::returnCode(Normal::FAIL,"sysUserName不能为空");
        }
        
        if( empty($requestData['refundType']) ) {
            return Normal::returnCode(Normal::FAIL,"售后方式refundType不能为空");
        }
        
        $refundType = (int)$requestData['refundType'];
        if( !isset(OrderRefund::instance()->refund_type[$refundType]) ) {
            return Normal::returnCode(Normal::FAIL,"售后方式refundType类型不正确");
        }
        
        //判断是否涉及退款
        if( OrderRefundMessage::instance()->isNeedRefundMoney($refundType) ) {
            
            if( empty($requestData['refundChannelSettlementMoney']) && (!isset($requestData['is_inner_call_mode']) || empty($requestData['is_inner_call_mode']))) {
                return Normal::returnCode(Normal::FAIL,"平台分摊结算金额refundChannelSettlementMoney不能为空");
            }
            
            if( empty($requestData['refundSupplierSettlementMoney']) && (!isset($requestData['is_inner_call_mode']) || empty($requestData['is_inner_call_mode']))) {
                return Normal::returnCode(Normal::FAIL,"供应商分摊结算金额refundSupplierSettlementMoney不能为空");
            }
        }
        
        $param['requestData'] = $requestData;
        
        //查询售后订单
        $res = $this->getSupplierOrderLists($param);
        if( $res['code'] != Normal::SUC ) {
            return $res;
        }
        $res['data']['order'] = $param['requestData'];
        $res['data']['binfo'] = $param['binfo'];
        $orderInfo      = current($res['data']['supplierOrderList']);
        $suppplierList  = $res['data']['suppplierList'];
        $orderGoodsList = $res['data']['newOrderGoods'];
        return $this->singleOrderAfterSaleVerify([
            'companyInfo'   => $suppplierList[$orderInfo['company_id']],
            'supplierOrder' => $orderInfo,
            'orderGoods'    => $orderGoodsList[$orderInfo['id']],
            'order'         => $res['data']['order'],
            'binfo'         => $res['data']['binfo'],
            'orderRefund'   => $res['data']['orderRefund']
        ]);
    }
    
    /**
     * 单个订单售后
     * @param array $param
     */
    public function singleOrderAfterSaleVerify(array $param)
    {
        if( empty($param['companyInfo']) || empty($param['supplierOrder']) || empty($param['orderGoods']) || empty($param['order']) || empty($param['binfo']) || empty($param['orderRefund']) )
        {
            return Normal::returnCode(Normal::FAIL,"except param companyInfo or supplierOrder or orderGoods or order or binfo or orderRefund");
        }
        
        $companyInfo    = $param['companyInfo'];
        $company_code   = $companyInfo['company_code'];
        $supplierClass  = ucFirst( $companyInfo['OrderDockMode'] == 1 ? 'normal' : $companyInfo['company_code'] );
        $serviceClass   = "App\\Service\\OrderService\\OrderRouteService\\{$supplierClass}";
        if( !class_exists($serviceClass) ) {
            return Normal::returnCode(Normal::FAIL,"{$serviceClass} not existed");
        }
    
        $requestMethod = 'orderAfterSale';
        if( !method_exists($serviceClass,$requestMethod) ) {
            return Normal::returnCode(Normal::FAIL,"{$serviceClass} {$requestMethod} methods not existed");
        }
    
        $supplierOrder      = $param['supplierOrder'];
        $orderGoods         = $param['orderGoods'];
        $order              = $param['order'];
        $binfo              = $param['binfo'];
        $orderRefund        = $param['orderRefund'];
        $param['apiBody']   = $companyInfo['apiBody'];
        //售后审核状态
        $afterVerifyStatus  = (int)$order['afterVerifyStatus'];
        $afterVerifyRemark  = $order['afterVerifyRemark'] ?? '';
        
        //要兼容以前的供应商
        $param['order']['exceptReason'] = $afterVerifyRemark;
        
        //判断是否是顶级云仓进行二审操作权限 除非上级云仓审核回调时候调用不校验
        if( $supplierOrder['is_top_system'] != 1 && $supplierOrder['order_push_status'] == 1 && (!isset($order['is_inner_call_mode']) || empty($order['is_inner_call_mode']))) {
            return Normal::returnCode(Normal::FAIL,"当前系统操作审核订单权限不够，请联系上游供应商系统运营进行操作审核！");
        }
        
        //售后订单ID
        $order_refund_id = $orderRefund['id'];
        
        //系统管理员信息
        $sys_user_id     = $order['sysUserID'];
        $sys_user_name   = $order['sysUserName'];
        
        //是否全部售后订单功能,如果是全部商品整单售后的情况下，才要通知供应商进行取消，否则走人工
        $afterVerifyAll = OrderRefundMessage::instance()->isOrderGoodsAllRefund($order_refund_id,$orderGoods);
        
        try {
            
            OrderSupplier::instance()->startTrans();
            
            $order_supplier_id = (string)$supplierOrder['id'];
            
            //写入售后订单日志申请
            if( $afterVerifyStatus == self::AFTER_SALE_VERIFY_PASS ) {
                OrderRefundLog::instance()->addLog($order_refund_id, "管理员:{$sys_user_name}，操作售后审核通过", $sys_user_id, $sys_user_name);
            } else {
                OrderRefundLog::instance()->addLog($order_refund_id, "管理员:{$sys_user_name}，操作售后审核拒绝", $sys_user_id, $sys_user_name);
            }
            
            //修改原始订单状态
            $update_after_sale_change = [
                'orderId'               => $order_supplier_id,
                'afterVerifyStatus'     => $afterVerifyStatus,
                'afterVerifyRemark'     => $afterVerifyRemark,
                'afterVerifyAll'        => $afterVerifyAll
            ];
            $res = $this->orderAfterSaleVerifyChange($update_after_sale_change);
            if( $res['code'] != Normal::SUC ) {
                OrderSupplier::instance()->rollback();
                return $res;
            }
            
            //付款审核方式
            $aftersale_verify_mode = $binfo['aftersale_verify_mode'];
            
            //通知BBC售后审核消息推送成功才发起调用供应商接口
            $body = [
                'orderSn'               => (string)$supplierOrder['order_sn'],
                'orderNo'               => (string)$supplierOrder['supplier_csn'],
                'afterVerifyTime'       => date("YmdHis"),
                'afterVerifyStatus'     => (string)$afterVerifyStatus,
                'afterVerifyRemark'     => (string)$afterVerifyRemark,
                'afterVerifyMode'       => (string)$aftersale_verify_mode,
                'afterVerifyModeName'   => Business::instance()->afterVerifyMode[$aftersale_verify_mode],
                'afterVerifyType'       => (string)$order['refundType'],
                'afterVerifyTypeName'   => OrderRefund::instance()->refund_type[$order['refundType']],
                'orderRefundId'         => (string)$orderRefund['id'],
            ];
            
            //修改售后订单的状态
            $result_refund_order = OrderRefundMessage::instance()->orderRefundVerify($orderRefund,$order);
            if( $result_refund_order['code'] != Normal::SUC ) {
                OrderSupplier::instance()->rollback();
                return $result_refund_order;
            }
            
            /*******************************同步渠道商订单功能*****************************/
            //发起推送渠道商接口数据
            if( $binfo['is_support_aftersale_verify'] == 1 && $supplierOrder['after_channel_notify_status'] != 1 && in_array($supplierOrder['order_type'],$this->channel_order_types) )
            {
                if($binfo['is_full_support_after_sale'] == 0){
                    //老版本只有这些字段推送
                    $body = [
                        'orderSn'           => $body['orderSn'],
                        'orderNo'           => $body['orderNo'],
                        'afterVerifyTime'   => $body['afterVerifyTime'],
                        'afterVerifyStatus' => $body['afterVerifyStatus'],
                        'afterVerifyRemark' => $body['afterVerifyRemark'],
                    ];
                }
                $result_channel = BusinessPushService::instance()->pushMessage('OrderAfterSaleVerifyNotify',$binfo,$body);
                $result_msg = $result_channel['msg'];
                //方便调试
                if( $result_channel['code'] != Normal::SUC )
                {
                    OrderSupplier::instance()->rollback();
                    OrderSupplier::instance()->where('id',$order_supplier_id)->update([
                        'after_channel_notify_status'  => 2,
                        'after_channel_notify_remark'  => $result_msg
                    ]);
                    return Normal::returnCode(Normal::FAIL,"渠道商接收售后审核结果失败『{$result_msg}』");
                }
                
                OrderSupplier::instance()->where('id',$order_supplier_id)->update([
                    'after_channel_notify_status'  => 1,
                    'after_channel_notify_remark'  => $result_msg
                ]);
                //下游不支持带商品部分售后的 不会有退款单
                if($afterVerifyStatus == self::AFTER_SALE_VERIFY_PASS && $binfo['is_full_support_after_sale'] == 0 ){
                    $updateExpressArr2 = [];
                    if($order['refundType'] == OrderRefundMessage::refund_type_refundnotgoodsbutmoney){
                        $updateExpressArr2['refund_status'] = OrderRefundMessage::refund_status_after_sale_success;
                    }
                    if($order['refundType'] == OrderRefundMessage::refund_type_goodsandmoney && $orderRefund['warehouse_change_status'] == 1){
                        $updateExpressArr2['refund_status'] = OrderRefundMessage::refund_status_after_sale_success;
                    }
                    if($updateExpressArr2){
                        OrderRefund::instance()->where('id',$order_refund_id)->update($updateExpressArr2);
                    }
                }
            }
            
			//新版本需求售后审核成功-进入财务阶段审核（财务审核通过之后才：通知下游，进入结算体系，通知供应商进行取消）
            OrderSupplier::instance()->commit();
            return Normal::returnCode(Normal::SUC,"审核处理完成！");
        } catch ( \Throwable $th) {
            OrderSupplier::instance()->rollback();
            return Normal::returnCode(Normal::FAIL,"二审操作失败，内部异常『{$th->getMessage()},{$th->getFile()},{$th->getLine()}』 ");
        }
    }
    
    /**
     * 获取供应商列表
     * @param array $param
     */
    public function getSupplierOrderLists( $param = [] )
    {
        $binfo       = $param['binfo'];
        $requestData = $param['requestData'];
        $orderRefund = OrderRefund::instance()->info(['ID'=>$requestData['refundID']]);
        if( empty($orderRefund) ) {
            return Normal::returnCode(Normal::FAIL,"申请售后订单记录不存在!");
        }
        
        //订单是否审核
        if( $orderRefund['refund_status'] != 1 ) {
            return Normal::returnCode(Normal::FAIL,"当前售后订单不在待审核状态，请核实订单审核状态！");
        }
        
        
        $bid = $binfo['bid'];
        $supplierOrderList = OrderSupplier::instance()
        ->select(OrderSupplier::instance()->order_fields)
        ->where('id',$orderRefund['sub_order_id'])
        ->where('bid',$bid)
        ->whereIn('order_status',[1,2])
        ->get()
        ->toArray();
        if( empty($supplierOrderList) ) {
            return Normal::returnCode(Normal::FAIL,"当前订单不满足待审核状态，请核对订单是否是已支付或者已发货状态，如果未支付的订单，请调用OrderCancel接口进行作废订单!");
        }
        
        //获取订单商品
        $osids  = array_column($supplierOrderList,'id');
        //获取订单商品
        $orderGoods = OrderSupplierGoods::instance()
        ->select(OrderSupplierGoods::instance()->goods_fields)
        ->where('bid',$bid)
        ->whereIn('order_id',$osids)
        ->get()
        ->toArray();
        
        if( empty($orderGoods) ) {
            return Normal::returnCode(Normal::FAIL,"获取订单数据失败");
        }
    
        //获取供应商结算数据
        $settlementOrderList = OrderSettlement::instance()
        ->select([
            'id',
            'order_id',
        ])
        ->where('bid',$bid)
        ->whereIn('order_id',$osids)
        ->where('settlement_type',2)
        ->where('settlement_mode',1)
        ->get()
        ->toArray();
        $settlementOrderList = array_column($settlementOrderList, null,'order_id');
    
        $supplierOrderList = array_map(function( & $value ) use ($settlementOrderList){
            //如果存在结算下单数据，则进行退款操作
            $value['isRecoverSettleMentMoney'] = isset($settlementOrderList[$value['id']]) ? true : false;
            return $value;
        },$supplierOrderList);
        
        $newOrderGoods = [];
        foreach ($orderGoods as $item ) {
            $newOrderGoods[$item['order_id']][] = $item;
            unset($item);
        }

        //获取供应商清单信息
        $companyIds = array_unique(array_column($supplierOrderList,'company_id'));
        $SupplierCompanyLists = SupplierCompany::instance()->getSupplierListByIds($companyIds);
        $SupplierCompanyLists = array_column($SupplierCompanyLists, null,'company_id');
        return Normal::returnCode(Normal::SUC,"订单数据获取成功",[
            'supplierOrderList' => $supplierOrderList,
            'newOrderGoods' => $newOrderGoods,
            'suppplierList' => $SupplierCompanyLists,
            'orderRefund'   => $orderRefund
        ]);
    }
    
    /**
     * 售后审核接口
     * $orderChanageArr['orderId']
     * $orderChanageArr['afterVerifyStatus']
     * $orderChanageArr['afterVerifyRemark']
     * $orderChanageArr['afterVerifyAll']
     * @return mixed
     */
    public function orderAfterSaleVerifyChange(array $orderChanageArr)
    {
        $time = time();
        $where = [
            ['id','=',$orderChanageArr['orderId']],
        ];
        $after_verify_status = $orderChanageArr['afterVerifyStatus'];
        $data = [
            'after_verify_status'   => $after_verify_status,
            'after_verify_remark'   => $orderChanageArr['afterVerifyRemark'],
            'after_verify_time'     => $time,
            'after_verify_all'      => $orderChanageArr['afterVerifyAll'],
            'md'                    => $time
        ];
        
        //审核拒绝的情况下,需要把是否售后恢复到未发起售后的状态
        if( $after_verify_status == self::AFTER_SALE_VERIFY_REJECT ) {
            $data['after_sale_status'] = 0;
            $data['after_sale_remark'] = '二审拒绝';
        }
        
        $res = OrderSupplier::instance()->edit($where,$data);
        if( !$res ) {
            return Normal::returnCode(Normal::FAIL,"当前订单售后审核状态变更失败，请检查是否已经审核通过!");
        }
        return Normal::returnCode(Normal::SUC,"操作成功");
    }
}